package com.warom.sdg.webview.jsinterface;

import android.content.Context;
import android.util.Log;

import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.warom.sdg.model.ApiResponse;
import com.warom.sdg.model.DeviceType;
import com.warom.sdg.model.DeviceTypeDto;
import com.warom.sdg.model.PlcDeviceEntity;
import com.warom.sdg.util.LogUtils;
import com.warom.sdg.util.ModbusTcpClient;
import com.warom.sdg.webview.BaseWebViewJsInterface;
import com.warom.sdg.webview.WebViewWrapper;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

/**
 * WebView JavaScript接口 - 设备管理
 * 处理设备相关的JavaScript调用
 */
public class WebViewJsDeviceInterface extends BaseWebViewJsInterface {

    /**
     * 构造函数
     * @param context 上下文
     * @param webViewWrapper WebView包装类，用于回调
     */
    public WebViewJsDeviceInterface(Context context, WebViewWrapper webViewWrapper) {
        super(context, webViewWrapper);
    }
    
    /**
     * 获取所有设备列表
     * @param requestId 请求ID
     */
    public void getDeviceList(String requestId) {
        executor.execute(() -> getDeviceList(result -> 
            handleAsyncResponse(requestId, result)));
    }
    
    /**
     * 根据ID获取设备详情
     * @param args 参数（设备ID）
     * @param requestId 请求ID
     */
    public void getDeviceById(String args, String requestId) {
        executor.execute(() -> getDeviceById(args, result -> 
            handleAsyncResponse(requestId, result)));
    }
    
    /**
     * 添加设备
     * @param args 参数（设备JSON）
     * @param requestId 请求ID
     */
    public void addDevice(String args, String requestId) {
        executor.execute(() -> addDevice(args, result -> 
            handleAsyncResponse(requestId, result)));
    }
    
    /**
     * 更新设备
     * @param args 参数（设备JSON）
     * @param requestId 请求ID
     */
    public void updateDevice(String args, String requestId) {
        executor.execute(() -> updateDevice(args, result -> 
            handleAsyncResponse(requestId, result)));
    }
    
    /**
     * 删除设备
     * @param args 参数（设备ID）
     * @param requestId 请求ID
     */
    public void deleteDevice(String args, String requestId) {
        executor.execute(() -> deleteDevice(args, result -> 
            handleAsyncResponse(requestId, result)));
    }
    
    /**
     * 测试设备连接
     * @param args 参数（设备ID）
     * @param requestId 请求ID
     */
    public void testDeviceConnection(String args, String requestId) {
        executor.execute(() -> testDeviceConnection(args, result -> 
            handleAsyncResponse(requestId, result)));
    }
    
    /**
     * 获取所有设备类型列表
     * @param requestId 请求ID
     */
    public void getDeviceTypeList(String args, String requestId) {
        try {
            LogUtils.logOperation("设备类型", "查询", "开始获取设备类型列表");
            
            // 使用同步方法直接获取设备类型列表
            List<DeviceType> deviceTypes = deviceTypeRepository.getAllDeviceTypesSync();
            
            // 转换为DTO对象
            List<DeviceTypeDto> deviceTypeDtos = new ArrayList<>();
            for (DeviceType type : deviceTypes) {
                deviceTypeDtos.add(DeviceTypeDto.fromDeviceType(type));
            }
            
            // 使用ApiResponse封装返回结果
            ApiResponse<List<DeviceTypeDto>> response = ApiResponse.success(deviceTypeDtos);
            LogUtils.logOperation("设备类型", "查询结果", "获取到 " + deviceTypes.size() + " 个设备类型");
            
            // 返回结果
            handleAsyncResponse(requestId, response.toJson());
        } catch (Exception e) {
            Log.e(TAG, "获取设备类型列表失败", e);
            LogUtils.logError("设备类型", "获取设备类型列表失败", e);
            // 使用ApiResponse返回错误信息
            ApiResponse<String> errorResponse = ApiResponse.error("获取设备类型列表失败: " + e.getMessage());
            handleAsyncResponse(requestId, errorResponse.toJson());
        }
    }
    
    /**
     * 获取所有设备列表 (异步版本，用于内部实现)
     * @param callback 回调函数，接收设备列表的JSON字符串
     */
    private void getDeviceList(Consumer<String> callback) {
        try {
            LogUtils.logOperation("设备管理", "查询", "开始获取设备列表");
            
            deviceRepository.getAllDevices(devices -> {
                try {
                    // 使用ApiResponse封装设备列表
                    ApiResponse<List<PlcDeviceEntity>> response = ApiResponse.success(devices);
                    LogUtils.logOperation("设备管理", "查询结果", "获取到 " + devices.size() + " 个设备");
                    callback.accept(response.toJson());
                } catch (Exception e) {
                    Log.e(TAG, "设备列表转换为JSON失败", e);
                    LogUtils.logError("设备管理", "转换JSON失败", e);
                    ApiResponse<String> errorResponse = ApiResponse.error("设备列表转换为JSON失败: " + e.getMessage());
                    callback.accept(errorResponse.toJson());
                }
            }, error -> {
                Log.e(TAG, "获取设备列表失败: " + error);
                LogUtils.logError("设备管理", "获取设备列表失败: " + error, null);
                ApiResponse<String> errorResponse = ApiResponse.error("获取设备列表失败: " + error);
                callback.accept(errorResponse.toJson());
            });
        } catch (Exception e) {
            Log.e(TAG, "获取设备列表失败", e);
            LogUtils.logError("设备管理", "获取设备列表失败", e);
            ApiResponse<String> errorResponse = ApiResponse.error("获取设备列表失败: " + e.getMessage());
            callback.accept(errorResponse.toJson());
        }
    }
    
    /**
     * 根据ID获取设备详情 (异步版本，用于内部实现)
     * @param deviceId 设备ID
     * @param callback 回调函数，接收设备详情的JSON字符串
     */
    private void getDeviceById(String deviceId, Consumer<String> callback) {
        try {
            int id = Integer.parseInt(deviceId);
            
            deviceRepository.getDeviceById(id, device -> {
                if (device != null) {
                    // 使用ApiResponse封装设备详情
                    ApiResponse<PlcDeviceEntity> response = ApiResponse.success(device);
                    callback.accept(response.toJson());
                } else {
                    // 设备不存在，返回错误信息
                    ApiResponse<String> errorResponse = ApiResponse.error("设备不存在");
                    callback.accept(errorResponse.toJson());
                }
            }, error -> {
                Log.e(TAG, "获取设备详情失败: " + error);
                ApiResponse<String> errorResponse = ApiResponse.error("获取设备详情失败: " + error);
                callback.accept(errorResponse.toJson());
            });
        } catch (Exception e) {
            Log.e(TAG, "获取设备详情失败", e);
            ApiResponse<String> errorResponse = ApiResponse.error("获取设备详情失败: " + e.getMessage());
            callback.accept(errorResponse.toJson());
        }
    }
    
    /**
     * 添加设备 (异步版本，用于内部实现)
     * @param deviceJson 设备信息的JSON字符串
     * @param callback 回调函数，接收操作结果
     */
    private void addDevice(String deviceJson, Consumer<String> callback) {
        try {
            // 使用静态Gson实例解析JSON数据
            PlcDeviceEntity device = gson.fromJson(deviceJson, PlcDeviceEntity.class);
            
            // 验证必要字段
            if (device.getDeviceName() == null || device.getDeviceName().isEmpty()) {
                ApiResponse<String> errorResponse = ApiResponse.error("设备名称不能为空");
                callback.accept(errorResponse.toJson());
                return;
            }
            
            if (device.getDeviceIp() == null || device.getDeviceIp().isEmpty()) {
                ApiResponse<String> errorResponse = ApiResponse.error("设备IP不能为空");
                callback.accept(errorResponse.toJson());
                return;
            }
            
            // 设置默认值
            device.setCreateTime(System.currentTimeMillis());
            device.setActive(false);
            
            // 如果前端传入的字段名与实体类不匹配，手动设置
            if (device.getDeviceType() == null && deviceJson.contains("type")) {
                try {
                    JsonObject jsonObject = JsonParser.parseString(deviceJson).getAsJsonObject();
                    if (jsonObject.has("type")) {
                        device.setDeviceType(jsonObject.get("type").getAsString());
                    }
                    if (jsonObject.has("deviceTypeId")) {
                        device.setDeviceTypeId(jsonObject.get("deviceTypeId").getAsInt());
                    }
                    if (jsonObject.has("name") && (device.getDeviceName() == null || device.getDeviceName().isEmpty())) {
                        device.setDeviceName(jsonObject.get("name").getAsString());
                    }
                    if (jsonObject.has("ip") && (device.getDeviceIp() == null || device.getDeviceIp().isEmpty())) {
                        device.setDeviceIp(jsonObject.get("ip").getAsString());
                    }
                    if (jsonObject.has("port") && device.getDevicePort() == 0) {
                        device.setDevicePort(jsonObject.get("port").getAsInt());
                    }
                    if (jsonObject.has("unitId") && device.getUnitId() == 0) {
                        device.setUnitId(jsonObject.get("unitId").getAsInt());
                    }
                } catch (Exception e) {
                    Log.e(TAG, "解析JSON字段失败", e);
                }
            }
            
            // 保存到数据库
            deviceRepository.insert(device, 
                id -> {
                    ApiResponse<String> response = ApiResponse.success("添加设备成功，ID: " + id);
                    callback.accept(response.toJson());
                }, 
                error -> {
                    Log.e(TAG, error);
                    ApiResponse<String> errorResponse = ApiResponse.error("保存失败: " + error);
                    callback.accept(errorResponse.toJson());
                });
        } catch (Exception e) {
            Log.e(TAG, "添加设备失败", e);
            ApiResponse<String> errorResponse = ApiResponse.error("添加设备失败: " + e.getMessage());
            callback.accept(errorResponse.toJson());
        }
    }
    
    /**
     * 更新设备 (异步版本，用于内部实现)
     * @param deviceJson 设备信息的JSON字符串
     * @param callback 回调函数，接收操作结果
     */
    private void updateDevice(String deviceJson, Consumer<String> callback) {
        try {
            // 使用静态Gson实例解析JSON数据
            PlcDeviceEntity device = gson.fromJson(deviceJson, PlcDeviceEntity.class);
            
            // 验证必要字段
            if (device.getDeviceId() <= 0) {
                // 尝试从JSON中直接获取id字段
                try {
                    JsonObject jsonObject = JsonParser.parseString(deviceJson).getAsJsonObject();
                    if (jsonObject.has("id")) {
                        device.setDeviceId(jsonObject.get("id").getAsInt());
                    }
                } catch (Exception e) {
                    Log.e(TAG, "解析JSON中的id字段失败", e);
                }
                
                if (device.getDeviceId() <= 0) {
                    callback.accept("设备ID无效");
                    return;
                }
            }
            
            if (device.getDeviceName() == null || device.getDeviceName().isEmpty()) {
                // 尝试从JSON中直接获取name字段
                try {
                    JsonObject jsonObject = JsonParser.parseString(deviceJson).getAsJsonObject();
                    if (jsonObject.has("name")) {
                        device.setDeviceName(jsonObject.get("name").getAsString());
                    }
                } catch (Exception e) {
                    Log.e(TAG, "解析JSON中的name字段失败", e);
                }
                
                if (device.getDeviceName() == null || device.getDeviceName().isEmpty()) {
                    callback.accept("设备名称不能为空");
                    return;
                }
            }
            
            if (device.getDeviceIp() == null || device.getDeviceIp().isEmpty()) {
                // 尝试从JSON中直接获取ip字段
                try {
                    JsonObject jsonObject = JsonParser.parseString(deviceJson).getAsJsonObject();
                    if (jsonObject.has("ip")) {
                        device.setDeviceIp(jsonObject.get("ip").getAsString());
                    }
                } catch (Exception e) {
                    Log.e(TAG, "解析JSON中的ip字段失败", e);
                }
                
                if (device.getDeviceIp() == null || device.getDeviceIp().isEmpty()) {
                    callback.accept("设备IP不能为空");
                    return;
                }
            }
            
            // 尝试获取其他字段
            try {
                JsonObject jsonObject = JsonParser.parseString(deviceJson).getAsJsonObject();
                if (jsonObject.has("port") && device.getDevicePort() == 0) {
                    device.setDevicePort(jsonObject.get("port").getAsInt());
                }
                if (jsonObject.has("type") && (device.getDeviceType() == null || device.getDeviceType().isEmpty())) {
                    device.setDeviceType(jsonObject.get("type").getAsString());
                }
                if (jsonObject.has("deviceTypeId")) {
                    device.setDeviceTypeId(jsonObject.get("deviceTypeId").getAsInt());
                }
                if (jsonObject.has("unitId") && device.getUnitId() == 0) {
                    device.setUnitId(jsonObject.get("unitId").getAsInt());
                }
            } catch (Exception e) {
                Log.e(TAG, "解析JSON中的其他字段失败", e);
            }
            
            // 获取当前设备信息并更新
            final PlcDeviceEntity updatingDevice = device;
            deviceRepository.getDeviceById(device.getDeviceId(), existingDevice -> {
                if (existingDevice != null) {
                    // 更新字段但保留一些原始数据
                    existingDevice.setDeviceName(updatingDevice.getDeviceName());
                    existingDevice.setDeviceIp(updatingDevice.getDeviceIp());
                    existingDevice.setDevicePort(updatingDevice.getDevicePort());
                    existingDevice.setUnitId(updatingDevice.getUnitId());
                    existingDevice.setDeviceType(updatingDevice.getDeviceType());
                    
                    // 执行更新
                    deviceRepository.update(existingDevice, 
                        () -> callback.accept("success"), 
                        error -> {
                            Log.e(TAG, error);
                            callback.accept("更新失败: " + error);
                        });
                } else {
                    callback.accept("更新失败，设备可能不存在");
                }
            }, error -> callback.accept("获取设备信息失败: " + error));
        } catch (Exception e) {
            Log.e(TAG, "更新设备失败", e);
            callback.accept("更新设备失败: " + e.getMessage());
        }
    }
    
    /**
     * 删除设备 (异步版本，用于内部实现)
     * @param deviceId 设备ID
     * @param callback 回调函数，接收操作结果
     */
    private void deleteDevice(String deviceId, Consumer<String> callback) {
        try {
            int id = Integer.parseInt(deviceId);
            
            // 执行删除操作
            deviceRepository.deleteById(id, 
                () -> callback.accept("success"), 
                error -> {
                    Log.e(TAG, error);
                    callback.accept("删除失败: " + error);
                });
        } catch (Exception e) {
            Log.e(TAG, "删除设备失败", e);
            callback.accept("删除设备失败: " + e.getMessage());
        }
    }
    
    /**
     * 测试设备连接 (异步版本，用于内部实现)
     * @param deviceId 设备ID
     * @param callback 回调函数，接收操作结果
     */
    private void testDeviceConnection(String deviceId, Consumer<String> callback) {
        try {
            int id = Integer.parseInt(deviceId);
            
            // 获取设备信息
            deviceRepository.getDeviceById(id, device -> {
                if (device == null) {
                    callback.accept("设备不存在");
                    return;
                }
                
                // 创建Modbus客户端并测试连接
                try {
                    ModbusTcpClient client = new ModbusTcpClient(
                            device.getDeviceIp(), 
                            device.getDevicePort(),
                            device.getUnitId());
                    
                    boolean connected = client.connect();
                    
                    // 断开连接
                    if (connected) {
                        client.disconnect();
                        
                        // 更新设备状态
                        device.setActive(true);
                        device.setLastConnectTime(System.currentTimeMillis());
                        deviceRepository.update(device, null, error -> 
                            Log.e(TAG, "更新设备状态失败: " + error));
                        
                        callback.accept("success");
                    } else {
                        callback.accept("连接失败，请检查设备IP和端口");
                    }
                } catch (Exception e) {
                    Log.e(TAG, "测试连接时出错", e);
                    callback.accept("测试连接失败: " + e.getMessage());
                }
            }, error -> callback.accept("获取设备信息失败: " + error));
        } catch (Exception e) {
            Log.e(TAG, "测试设备连接失败", e);
            callback.accept("测试连接失败: " + e.getMessage());
        }
    }
} 